package com.alks.common.utils.beanutils;


import com.alibaba.druid.util.StringUtils;

import java.lang.reflect.Field;
import java.util.List;
import java.util.stream.Collectors;


public class BeanUtil extends cn.hutool.core.bean.BeanUtil {

    /**
     * 将原对象转换成目标对象，对于字段不匹配的字段可以使用转换器处理
     *
     * @param source  原对象
     * @param clazz   目标对象的class
     * @param convert 转换器
     * @param <R>     原对象类型
     * @param <T>     目标对象类型
     * @return 目标对象
     */
    public static <R, T> T copyBean(R source, Class<T> clazz, Convert<R, T> convert) {
        T target = copyBean(source, clazz);
        if (convert != null) {
            convert.convert(source, target);
        }
        return target;
    }

    /**
     * 将原对象转换成目标对象，对于字段不匹配的字段可以使用转换器处理
     *
     * @param source 原对象
     * @param clazz  目标对象的class
     * @param <R>    原对象类型
     * @param <T>    目标对象类型
     * @return 目标对象
     */
    public static <R, T> T copyBean(R source, Class<T> clazz) {
        if (source == null) {
            return null;
        }
        return toBean(source, clazz);
    }

    public static <R, T> List<T> copyList(List<R> list, Class<T> clazz) {
        if (list == null || list.size() == 0) {
            return CollUtils.emptyList();
        }
        return copyToList(list, clazz);
    }

    public static <R, T> List<T> copyList(List<R> list, Class<T> clazz, Convert<R, T> convert) {
        if (list == null || list.size() == 0) {
            return CollUtils.emptyList();
        }
        return list.stream().map(r -> copyBean(r, clazz, convert)).collect(Collectors.toList());
    }

    /**
     * 验证对象各个属性是否为空,不适用于有isEmpty方法的类型
     *
     * @param bean 判空元素
     * @return true为空
     */
    public static boolean allIsEmpty(Object bean) {
        if (bean == null) {
            return true;
        }
        // 验证对象的所有属性是否为空
        for (Field field : bean.getClass().getDeclaredFields()) {
            field.setAccessible(true);
            try {
                Object value = field.get(bean);
                if (value != null) {
                    if (value instanceof String) {
                        if (!StringUtils.isEmpty((String) value)) {
                            return false;
                        }
                    } else {
                        return false;
                    }
                }
            } catch (IllegalAccessException e) {
                e.printStackTrace();
            }
        }
        return true;
    }

    /**
     * 字符串简单判空
     *
     * @param bean
     * @return
     */
    public static boolean stringIsEmpty(String bean) {
        return bean == null || bean.isEmpty();
    }

    public static void setNoEmpty(Object object) throws IllegalAccessException {
        Class<?> clazz = object.getClass();
        Field[] fields = clazz.getDeclaredFields();
        for (Field field : fields) {
            field.setAccessible(true);
            Object value = field.get(object);
            if (value == null) {
                Class<?> fieldType = field.getType();
                Object initialValue = getInitialValue(fieldType);
                field.set(object, initialValue);
            }
        }
    }

    private static Object getInitialValue(Class<?> fieldType) {
        if (fieldType == String.class) {
            return "";
        } else if (fieldType == int.class || fieldType == Integer.class) {
            return 0;
        } else if (fieldType == boolean.class || fieldType == Boolean.class) {
            return false;
        } else if (fieldType == double.class || fieldType == Double.class) {
            return 0.0;
        } else if (fieldType == float.class || fieldType == Float.class) {
            return 0.0f;
        } else if (fieldType == long.class || fieldType == Long.class) {
            return 0L;
        } else if (fieldType == short.class || fieldType == Short.class) {
            return (short) 0;
        } else if (fieldType == byte.class || fieldType == Byte.class) {
            return (byte) 0;
        } else {
            return null;
        }
    }

}
